package com.lv.utils;


import com.dingtalk.oapi.lib.aes.DingTalkJsApiSingnature;
import com.dingtalk.open.client.ServiceFactory;
import com.dingtalk.open.client.api.model.corp.CorpUserBaseInfo;
import com.dingtalk.open.client.api.model.corp.CorpUserDetail;
import com.dingtalk.open.client.api.model.corp.JsapiTicket;
import com.dingtalk.open.client.api.service.corp.CorpConnectionService;
import com.dingtalk.open.client.api.service.corp.CorpUserService;
import com.dingtalk.open.client.api.service.corp.JsapiService;
import com.dingtalk.open.client.common.SdkInitException;
import com.dingtalk.open.client.common.ServiceException;
import com.dingtalk.open.client.common.ServiceNotExistException;
import com.lv.bean.Token;
import com.lv.dao.TokenDao;
import com.lv.dao.TokenDaoImpl;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;

/**
 * AccessToken和jsticket的获取封装
 */
public class AuthHelper {

    // 调整到1小时50分钟
    public static final long cacheTime = 1000 * 60 * 55 * 2;

    /*
     * 在此方法中，为了避免频繁获取access_token，
     * 在距离上一次获取access_token时间在两个小时之内的情况，
     * 将直接从持久化存储中读取access_token
     *
     * 因为access_token和jsapi_ticket的过期时间都是7200秒
     * 所以在获取access_token的同时也去获取了jsapi_ticket
     * 注：jsapi_ticket是在前端页面JSAPI做权限验证配置的时候需要使用的
     * 具体信息请查看开发者文档--权限验证配置
     */
    public static Token getTokenAndTicket() throws OApiException{
        long curTime = System.currentTimeMillis();
        TokenDao tokenDao=new TokenDaoImpl();
        Token token = tokenDao.selectTokenByCorpId(Env.CORP_ID);
        String accToken = "";
        String jsTicket = "";
        Token token1=null;
        if (token==null){
            try {
                ServiceFactory serviceFactory = ServiceFactory.getInstance();
                CorpConnectionService corpConnectionService = serviceFactory.getOpenService(CorpConnectionService.class);
                accToken = corpConnectionService.getCorpToken(Env.CORP_ID, Env.CORP_SECRET);
                JsapiService jsapiService = serviceFactory.getOpenService(JsapiService.class);
                JsapiTicket JsapiTicket = jsapiService.getJsapiTicket(accToken, "jsapi");
                jsTicket = JsapiTicket.getTicket();
                token1 = new Token();
                token1.setAccess_token(accToken);
                token1.setBegin_time(curTime);
                token1.setTicket(jsTicket);
                token1.setCorp_id(Env.CORP_ID);
                tokenDao.insertToken(token1);
            } catch (ServiceException e) {
                e.printStackTrace();
            } catch (ServiceNotExistException e) {
                e.printStackTrace();
            } catch (SdkInitException e) {
                e.printStackTrace();
            }
        }else{
            if (token.getAccess_token() == null || curTime - token.getBegin_time() >= cacheTime) {
                try {
                    ServiceFactory serviceFactory = ServiceFactory.getInstance();
                    CorpConnectionService corpConnectionService = serviceFactory.getOpenService(CorpConnectionService.class);
                    accToken = corpConnectionService.getCorpToken(Env.CORP_ID, Env.CORP_SECRET);
                    JsapiService jsapiService = serviceFactory.getOpenService(JsapiService.class);
                    JsapiTicket JsapiTicket = jsapiService.getJsapiTicket(accToken, "jsapi");
                    jsTicket = JsapiTicket.getTicket();
                    token1 = new Token();
                    token1.setAccess_token(accToken);
                    token1.setBegin_time(curTime);
                    token1.setTicket(jsTicket);
                    token1.setCorp_id(Env.CORP_ID);
                    tokenDao.updateToken(token1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                token1 = new Token();
                accToken=token.getAccess_token();
                jsTicket=token.getTicket();
                token1.setAccess_token(accToken);
                token1.setTicket(jsTicket);
            }
        }
        return token1;
    }

    public static String sign(String ticket, String nonceStr, long timeStamp, String url) throws OApiException {
        try {
            return DingTalkJsApiSingnature.getJsApiSingnature(url, nonceStr, timeStamp, ticket);
        } catch (Exception ex) {
            throw new OApiException(0, ex.getMessage());
        }
    }


    /**
     * 计算当前请求的jsapi的签名数据<br/>
     * <p>
     * 如果签名数据是通过ajax异步请求的话，签名计算中的url必须是给用户展示页面的url
     * @param request
     * @return
     */
    @SuppressWarnings("deprecation")
	public static String getConfig(HttpServletRequest request) {

        String urlString = request.getRequestURL().toString();
        String queryString = request.getQueryString();
        String queryStringEncode = null;
        String url;
        if (queryString != null) {
            queryStringEncode = URLDecoder.decode(queryString);
            url = urlString + "?" + queryStringEncode;
        } else {
            url = urlString;
        }

        String nonceStr = "abcdef";//只能是6位字符
        long timeStamp = System.currentTimeMillis() / 1000;
        String signedUrl = url;
        String ticket = null;
        String signature = null;
        String agentid = null;

        try {
            ticket = AuthHelper.getTokenAndTicket().getTicket();
            signature = AuthHelper.sign(ticket, nonceStr, timeStamp, signedUrl);
            agentid = "175059231";

        } catch (OApiException e) {
            e.printStackTrace();
        }
        String configValue = "{jsticket:'" + ticket + "',signature:'" + signature + "',nonceStr:'" + nonceStr + "',timeStamp:'"
                + timeStamp + "',corpId:'" + Env.CORP_ID + "',agentid:'" + agentid + "'}";
        return configValue;
    }


  /*  public static String getSsoToken() throws OApiException {
        String url = "https://oapi.dingtalk.com/sso/gettoken?corpid=" + Env.CORP_ID + "&corpsecret=" + Env.SSO_Secret;
        JSONObject response = HttpHelper.httpGet(url);
        String ssoToken;
        if (response.containsKey("access_token")) {
            ssoToken = response.getString("access_token");
        } else {
            throw new OApiException("Sso_token");
        }
        return ssoToken;

    }*/


    //获取成员
    public static CorpUserDetail getUser(String accessToken, String userid) throws Exception {

        CorpUserService corpUserService = ServiceFactory.getInstance().getOpenService(CorpUserService.class);
        return corpUserService.getCorpUser(accessToken, userid);
    }


    public static CorpUserBaseInfo getUserInfo(String accessToken, String code) throws Exception {
        CorpUserService corpUserService = ServiceFactory.getInstance().getOpenService(CorpUserService.class);
        return corpUserService.getUserinfo(accessToken, code);
    }
}
